package com.will.txj.wy.files.config;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

/**
 * @author: wen-yi;
 * @date: 2021/12/4 13:55;
 * @Description:
 */
@Component
public class SftpClientFactory implements PooledObjectFactory<ChannelSftp> {
    @Autowired
    private SftpConfig config;

    //当需要新对象时调用，创建对象
    @Override
    public PooledObject<ChannelSftp> makeObject() throws Exception {
        JSch jsch = new JSch();
        if (config.getPrivateKey() != null) {
            jsch.addIdentity(config.getPrivateKey());// 设置私钥
        }

        Session session = jsch.getSession(config.getUsername(), config.getHost(), config.getPort());
        if (config.getPassword() != null) {
            session.setPassword(config.getPassword());
        }

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();

        Channel channel = session.openChannel("sftp");
        channel.connect();
        return new DefaultPooledObject<>((ChannelSftp) channel);
    }

    //销毁连接，当连接池空闲数量达到上限时，调用此方法销毁连接
    @Override
    public void destroyObject(PooledObject<ChannelSftp> pooledObject) throws Exception {
        ChannelSftp sftp = pooledObject.getObject();
        if (sftp.isConnected()) {
            sftp.disconnect();
        }
    }

    //从池中取对象或归还对象到池中时，判断对象安全
    @Override
    public boolean validateObject(PooledObject<ChannelSftp> pooledObject) {
        ChannelSftp sftp = pooledObject.getObject();
        return sftp.isConnected();
    }

    //从池中取出对象，使用前，再次初始化对象
    @Override
    public void activateObject(PooledObject<ChannelSftp> pooledObject) throws Exception {

    }

    //钝化连接，使链接变为可用状态-当对象返回到空闲池时调用
    @Override
    public void passivateObject(PooledObject<ChannelSftp> pooledObject) throws Exception {
        ChannelSftp sftp = pooledObject.getObject();
        sftp.cd(config.getFilepath()); // sftp.cd(config.getRoot());
    }

    //用于连接池中获取pool属性
    public SftpConfig getConfig() {
        return config;
    }
}
